home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™94
/
Talks & Papers
/
Michael D. Crawford↵
/
Word Services SDK 1.0.5
/
Writeswell Jr. Source
/
MyFiles.c
< prev
next >
Wrap
Text File
|
1993-03-17
|
10KB
|
504 lines
/* MyFiles.c
* Handle file calls in IAC speller testbed app
* ©1992 Working Software, Inc.
* This source code is copyrighted. Permission is granted to use the Word Services
* portion of the Writeswell Jr. source code in your own programs, but you
* may not distribute the Writeswell Jr. word-processor code as a
* commercial product. If you modify the code, please do not call it
* Writeswell Jr. (or Writeswell.) This will ensure that people understand the
* program and don’t have to deal with a number of different versions with
* who-knows-what going on in the code.
*
* Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
* 6 Sep 91 Mike Crawford
*/
#include <Files.h>
#include "MyFiles.h"
#include "AppleEvents.h"
#include "TBConstants.h"
#include "TBGlobals.h"
#include "TestBed.h"
#include "Scroll.h"
#include "Gripe.h"
#include "FontMenu.h"
#define kZoomIconAllowance 68 /* Width of desktop to show when window zoomed */
OSErr SaveStyleResource( void );
Boolean AskSave( void );
void DoOpenDialog( void )
{
SFTypeList typeList;
SFReply reply;
Point where;
OSErr err;
typeList[ 0 ] = 'TEXT';
/* STUB Center the dialog */
where.h = 50;
where.v = 50;
SFGetFile( where,
"\p",
(FileFilterProcPtr)NULL,
1,
typeList,
(DlgHookProcPtr)NULL,
&reply );
if ( !reply.good )
return;
MyOpenSfFile( &reply );
return;
}
void DoSave( void )
{
Boolean saved;
if ( gDocExists )
SaveFile();
else
DoSaveDialog( &saved );
return;
}
OSErr DoSaveAs( void )
{
OSErr err;
short oldRefNum;
short oldResRefNum;
Boolean docExisted;
Boolean saved;
docExisted = gDocExists;
if ( docExisted ){
oldRefNum = gRefNum;
oldResRefNum = gResRefNum;
}
err = DoSaveDialog( &saved );
if ( docExisted && saved ){
err = FSClose( oldRefNum );
if ( err ){
Gripe( "\pCould not close original file" );
return err;
}
if ( oldResRefNum != -1 ){
CloseResFile( oldResRefNum );
err = ResError();
if ( err ){
Gripe( "\pCould not close original resource file" );
return err;
}
}
}
return noErr;
}
OSErr DoSaveDialog( Boolean *savedPtr )
{
SFReply reply;
OSErr err;
Point where;
*savedPtr = false;
/* STUB Center the dialog on the screen */
where.h = 100;
where.v = 50;
/* STUB use the window name as the default name */
SFPutFile( where,
"\pSave document as:",
"\pUntitled",
(ProcPtr)NULL,
&reply );
if ( !reply.good )
return noErr;
/* Try deleting the old file. It may not exist.
* STUB Do a GetFileInfo to see if the file already exists
*/
err = FSDelete( reply.fName, reply.vRefNum );
if ( err && err != fnfErr ){
Gripe( "\pCould not delete existing file" );
return err;
}
err = Create( reply.fName,
reply.vRefNum,
'MiKe',
'TEXT' );
if ( err ){
Gripe( "\pCould not create new file" );
return err;
}
if ( err = FSOpen( reply.fName, reply.vRefNum, &gRefNum ) ){
Gripe( "\pFSOpen failed" );
return err;
}
err = SetVol( (StringPtr)NULL, reply.vRefNum );
if ( err ){
Gripe( "\pCould not set volume" );
return err;
}
CreateResFile( reply.fName );
if ( err = ResError() ){
Gripe( "\pCould not create resource fork of document" );
return err;
}
gResRefNum = OpenResFile( reply.fName );
if ( gResRefNum == -1 ){
err = ResError();
Gripe( "\pOpenResFile failed" );
return err;
}
gDocExists = true;
err = SaveFile();
if ( !err ){
SetWTitle( gDocWindow, reply.fName );
*savedPtr = true;
}
return err;
}
OSErr SaveFile( void )
{
OSErr err;
TEHandle textH;
CharsHandle textBufHdl;
long numChars;
/* STUB should do a "safe save" here. This is not a safe save - if there is
* a failure in here, the file is hosed.
*/
err = SetFPos( gRefNum, fsFromStart, 0L );
if ( err ){
Gripe( "\pCould not set file position" );
return err;
}
err = SetEOF( gRefNum, 0L );
if ( err ){
Gripe( "\pCould not set end of file" );
return err;
}
textH = (TEHandle)GetWRefCon( gDocWindow );
textBufHdl = TEGetText( textH );
numChars = GetHandleSize( textBufHdl );
HLock( textBufHdl );
err = FSWrite( gRefNum, &numChars, *textBufHdl );
HUnlock( textBufHdl );
if ( err ){
Gripe( "\pFSWrite failed" );
return err;
}
err = SaveStyleResource();
if ( !err )
gDocDirty = false;
return err;
}
OSErr SaveStyleResource( void )
{
short curFile;
StScrpHandle styleHdl;
TEHandle textH;
Handle oldStyle;
short oldStart;
short oldEnd;
curFile = CurResFile();
UseResFile( gResRefNum );
textH = (TEHandle)GetWRefCon( gDocWindow );
oldStart = (*textH)->selStart;
oldEnd = (*textH)->selEnd;
(*textH)->selStart = 0;
(*textH)->selEnd = 32767;
styleHdl = GetStylScrap( textH );
(*textH)->selStart = oldStart;
(*textH)->selEnd = oldEnd;
if ( !styleHdl ){
UseResFile( curFile );
return memFullErr;
}
oldStyle = Get1Resource( 'styl', rStyleID );
if ( oldStyle ){
RmveResource( oldStyle );
}
AddResource( styleHdl, 'styl', rStyleID, "\pText Styles" );
ChangedResource( styleHdl );
WriteResource( styleHdl );
UpdateResFile( gResRefNum );
UseResFile( curFile );
return noErr;
}
OSErr MyOpenSfFile( SFReply *replyPtr )
{
OSErr err;
Rect txRect;
char *textBuf;
long bytesRead;
TEHandle textH;
StScrpHandle styleHdl;
ParamBlockRec fPB;
long fileSize;
if ( err = FSOpen( replyPtr->fName, replyPtr->vRefNum, &gRefNum ) ){
Gripe( "\pFSOpen failed" );
return err;
}
fPB.fileParam.ioCompletion = (ProcPtr)NULL;
fPB.fileParam.ioNamePtr = (StringPtr)NULL;
fPB.fileParam.ioVRefNum = replyPtr->vRefNum;
err = PBSetVol( &fPB, false );
if ( err ){
Gripe( "\pPBSetVol failed in MyOpenSfFile" );
return err;
}
gResRefNum = OpenResFile( replyPtr->fName );
/* The existing file may have had no resource fork. It's not clear to me
* what the right thing to do is. I am inclined to not create one - if the
* user wants to save styles, she could do a "Save As" to create a new file
* with the style resource.
*/
styleHdl = (StScrpHandle)NULL; /* In case there's no resource fork */
if ( gResRefNum != -1 ){
/* Load the style resource */
styleHdl = (StScrpHandle)Get1Resource( 'styl', rStyleID );
/* styleHdl might be nil - we check for this later */
}
if ( MakeNewWindow() ){
Gripe( "\pMakeNewWindow failed" );
return err;
}
gDocExists = true;
SetWTitle( gDocWindow, replyPtr->fName );
textH = (TEHandle)GetWRefCon( gDocWindow );
/* Styled TextEdit requires that we insert the text and the style at the same time.
* I originally had a loop that did a read with a small buffer, but in order to
* set both the text and the style, I need to read all of the text in a single
* chunk, and set it in a single chunk.
*/
err = GetEOF( gRefNum, &fileSize );
if ( err ){
Gripe( "\pCould not get file size" );
return err;
}
textBuf = NewPtr( fileSize );
if ( !textBuf ){
Gripe( "\pOut of memory" );
return memFullErr;
}
bytesRead = fileSize;
err = FSRead( gRefNum, &bytesRead, textBuf );
if ( err ){
Gripe( "\pCould not read the file" );
DisposPtr( textBuf );
return err;
}
/* styleHdl might be nil. This is OK */
TEStylInsert( textBuf, bytesRead, styleHdl, textH );
if ( styleHdl != (StScrpHandle)NULL );
ReleaseResource( styleHdl );
TESetSelect( 0L, 0L, textH );
SetVertScroll( gDocWindow, gVertScroll );
return noErr;
}
OSErr MyOpenSpecFile( FSSpec *specPtr )
{
WDPBRec wPB;
SFReply reply;
OSErr err;
wPB.ioCompletion = (ProcPtr)NULL;
wPB.ioVRefNum = specPtr->vRefNum;
wPB.ioWDDirID = specPtr->parID;
wPB.ioWDProcID = 'ERIK'; /* This is traditional; no real point to it */
wPB.ioNamePtr = (StringPtr)NULL;
err = PBOpenWD( &wPB, false );
if ( err ){
Gripe( "\pPBOpenWD failed in MyOpenSpecFile" );
return err;
}
BlockMove( specPtr->name, reply.fName, (specPtr->name)[0] + 1 );
reply.vRefNum = wPB.ioVRefNum;
reply.good = true;
reply.copy = false;
reply.fType = 'TEXT'; /* STUB Do a GetFileInfo to find the type */
reply.version = 0;
err = MyOpenSfFile( &reply );
return err;
}
OSErr MakeNewWindow( void )
{
OSErr err;
Rect txRect;
TEHandle textH;
Rect *zoomArray;
gDocWindow = GetNewWindow( kDocWindowID, (Ptr)NULL, (WindowPtr) -1 );
if ( !gDocWindow ){
Gripe( "\pGetNewWindow failed" );
return err;
}
SetPort( gDocWindow );
gDocDirty = false;
gDocExists = false;
GetTERect( &( thePort->portRect ), &txRect );
textH = TEStylNew( &txRect, &txRect );
if ( !textH ){
Gripe( "\pTENew failed" );
return memFullErr;
}
SetWRefCon( gDocWindow, (long)textH );
gVertScroll = GetNewControl( kVertScrollBarID, gDocWindow );
if ( !gVertScroll )
return memFullErr;
( *textH )->clikLoop = (ProcPtr)TrackContentClick;
SizeVertScroll();
SetVertScroll( gDocWindow, gVertScroll );
if ( ((WindowPeek)gDocWindow)->dataHandle != (Handle)NULL ){
/* Set the zoom state to reveal the disk & trash icons.
* STUB Make this some kind of preference - inappropriate for Unifinder
*/
zoomArray = (Rect*)*((WindowPeek)gDocWindow)->dataHandle; /* Warning: Deref handle */
zoomArray[ 1 ].right -= kZoomIconAllowance;
}
return noErr;
}
void DoCloseWindow( void )
{
Boolean saveIt;
if ( gDocDirty ){
saveIt = AskSave();
if ( saveIt )
DoSave();
}
TEDispose( (TEHandle)GetWRefCon( gDocWindow) );
DisposeWindow( gDocWindow );
gDocWindow = (WindowPtr)NULL;
if ( gDocExists ){
/* If the file exists on disk, close it */
FSClose( gRefNum );
if ( gResRefNum != -1 )
CloseResFile( gResRefNum );
}
FixMenuMarks(); /* Disable menu items to reflect absent window */
return;
}
Boolean AskSave( void )
{
short item;
item = Alert( rAskSaveID, (ProcPtr)NULL );
if ( item == kASSave )
return true;
return false;
}